package com.zecan.blog.filter;

import com.zecan.blog.dao.UserMapper;
import com.zecan.blog.entity.BlogUser;
import com.zecan.blog.service.BlogUserService;
import com.zecan.blog.utils.BlogConstant;
import com.zecan.blog.utils.JWTUtils;
import com.zecan.blog.utils.SpringUtils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

/**
 * @ClassName JwtAuthenticationFilter
 * @Description
 * @date 2022/10/29 15:53
 * @Version 1.0
 */

public class JwtAuthenticationFilter extends BasicAuthenticationFilter {


   JWTUtils jwtUtils   = SpringUtils.getBean(JWTUtils.class);


   BlogUserService blogUserService = SpringUtils.getBean(BlogUserService.class);

   UserMapper userMapper = SpringUtils.getBean(UserMapper.class);

    // 用户service

    // userDetailServiceImpl 实现

    public JwtAuthenticationFilter(AuthenticationManager authenticationManager) {
        super(authenticationManager);
    }

    // jwt 验证
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        String jwt = request.getHeader(jwtUtils.getHeader());

        // 不存在jwt 则直接往后继续执行
        if(StringUtils.isBlank(jwt)) {
            chain.doFilter(request,response);
            return;
        }

        //获取jwt 并解析
        Claims claim = jwtUtils.getClaimsByToken(jwt);
        if (claim == null) {
            throw new JwtException("token 异常");
        }
        if (jwtUtils.isTokenExpired(claim)) {
            throw new JwtException("token 已过期");
        }
//        // claims 为 保存在jwt中的用户信息 进行解析获取用户信息， 每次访问的时候保存用户的信息
        String username = claim.getSubject();

            // 获取用户信息
            BlogUser blogUser = blogUserService.selectUserByUsername(username);


        //保存到securityContextHolder中
        //构建UsernamePasswordAuthenticationToken,这里密码为null，是因为提供了正确的JWT,实现自动登录
        SecurityContextHolder.getContext().setAuthentication(
                new UsernamePasswordAuthenticationToken(
                        username, null, getAuthentication(blogUser.getUserRole()))
                );

        chain.doFilter(request,response);
    }


    /**
     * 根据用户信息获取用户权限
     * @param role
     * @return
     */
    private List<GrantedAuthority> getAuthentication(Integer role) {
        List<GrantedAuthority> authorityList= null;
        // 保存权限信息
        switch (role) {
            case 0 :
                authorityList =  AuthorityUtils.createAuthorityList(BlogConstant.BLOG_NORMAL_USER);
                break;
            case 1:
                authorityList =   AuthorityUtils.createAuthorityList(BlogConstant.BLOG_ADMIN);
                break;
        }

        return  authorityList;
    }

}
